package cn.elwy.rcp.ui.table.provider;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Collection;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

import cn.elwy.rcp.core.model.ui.tree.TreeElement;

/**
 * 内容提供者类，支持树、表格、列表等控件
 * @author huangsq
 * @version 2.0, 2015-11-03
 * @since 1.0, 2015-02-19
 */
public class TablePaneContentProvider implements ITreeContentProvider {

  private static final Object[] NO_CHILDREN = new Object[0];

  @Override
  public Object[] getElements(Object element) {
    return getChildren(element);
  }

  @Override
  public Object[] getChildren(Object element) {
    if (element instanceof Collection) {
      return ((Collection<?>) element).toArray();
    } else if (element instanceof Object[] || element instanceof Array) {
      return (Object[]) element;
    } else if (element instanceof TreeElement) {
      return ((TreeElement) element).getChildren();
    }
    try {
      Method method = getMethod(element.getClass(), "getChildren");
      if (method != null) {
        Object children = method.invoke(element);
        if (children instanceof Collection) {
          return ((Collection<?>) children).toArray();
        } else if (children instanceof Object[] || children instanceof Array) {
          return (Object[]) children;
        }
      }
    } catch (Exception e) {
    }
    return NO_CHILDREN;
  }

  @Override
  public Object getParent(Object element) {
    if (element instanceof TreeElement) {
      return ((TreeElement) element).getParent();
    } else {
      return null;
    }
  }

  @Override
  public boolean hasChildren(Object element) {
    if (element instanceof TreeElement) {
      TreeElement treeNode = (TreeElement) element;
      if (treeNode.isDynamic()) {
        return true;
      } else {
        return treeNode.hasChildren();
      }
    } else {
      Object[] childrent = getChildren(element);
      return childrent != null && childrent.length > 1;
    }
  }

  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  }

  @Override
  public void dispose() {
  }

  /**
   * 利用递归找一个类的指定方法，如果找不到，去父亲里面找直到最上层Object对象为止。
   * @param clazz 目标类
   * @param methodName 方法名
   * @param argsType 方法参数类型
   * @return 对象的方法
   * @throws NoSuchMethodException
   */
  public static Method getMethod(Class<?> clazz, String methodName, final Class<?>... argsType)
      throws NoSuchMethodException {
    Method method = null;
    try {
      method = clazz.getMethod(methodName, argsType);
    } catch (NoSuchMethodException e) {
      try {
        method = clazz.getDeclaredMethod(methodName, argsType);
      } catch (NoSuchMethodException ex) {
        if (clazz.getSuperclass() == null) {
          return method;
        } else {
          return getMethod(clazz.getSuperclass(), methodName, argsType);
        }
      }
    }
    // 调用private方法的关键一句话
    method.setAccessible(true);
    return method;
  }

}
